在周志明的深入理解Java虚拟机第二版这本书里对GC描述有这么一段话。
新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也非常快。
老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随着至少一次Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC 的速度一般会比Minor GC慢10倍以上。
这里对GC的分类其实有一点问题,Major/FullGC并不一定仅仅只发生在老年代,对于HotSpot VM来说,它里面的GC其实只分为两大种。
Partial GC: 并不收集整个堆的模式
- Young GC/Minor GC:只收集新生代的GC
- OId GC:只收集老年代的GC。目前只有CMS的Concurrent collection是这个模式。
- Mixed GC:收集整个新生代以及部分老年代的GC,目前只有G1有这个模式。
Full GC:收集整个堆,包括新生代,老年代、永久代(如果存在的话)等所有部分的模式。
Major GC通常是跟full GC是等价的,收集整个GC堆。但因为HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了,当有人说“major GC”的时候一定要问清楚他想要指的是上面的full GC还是old GC。
最简单的分代式GC策略,按HotSpot VM的serial GC的实现来看,触发条件是:
- young GC:当young gen中的eden区分配满的时候触发。注意young GC中有部分存活对象会晋升到old gen,所以young GC后old gen的占用量通常会有所升高。
- full GC:当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC);或者,如果有perm gen的话,要在perm gen分配空间但已经没有足够空间时,也要触发一次full GC;或者System.gc()、heap dump带GC,默认也是触发full GC。